<?php 
class CartWS_Model_SalesOrderLine extends CartWS_Model_FormulaEngine_Table 
{
    const LINE_TYPE_PRODUCT = 'PRODUCT';
    const LINE_TYPE_PROMOTION = 'PROMOTION';
    const LINE_TYPE_PAYMENT_METHOD_CHARGE = 'PAYMENT_METHOD_CHARGE';
    const LINE_TYPE_SHIPPING_COST = 'SHIPPING_COST';
    const INIT_LINE_ORDER = 101;

    protected $_name = 'sc_sales_order_line';
    protected $_sequence = 'sc_sales_order_line_seq';
    protected $_primary = 'sales_line_id';
    //protected $_dependentTables = array( 'Default_Model_SalesLineProperty' );
    protected $_referenceMap = array(
    'SalesOrderHdr' => array(
    'columns'           => array( 'sales_order_id' ),
    'refTableClass'     => 'Default_Model_SalesOrderHdr',
    'refColumns'        => array( 'sales_order_id' )
    ),
    'CartWS_Model_SalesOrderHdr' => array(
    'columns'           => 'sales_order_id',
    'refTableClass'     => 'CartWS_Model_SalesOrderHdr',
    'refColumns'        => 'sales_order_id'
    )
    );

    /**
     *
     * Determina el precio final de la linea a partir de la cantidad de items. precio unitario, impuestos.
     * @param mixed SalesOrderLineRow
     * @return float Total
     */
    public function calculateFinalPrice( $row ) {
        if( ! is_array( $row ) ) {
            $row = $row->toArray();
        }
        $sub = (( $row['ordered_quantity'] * $row['unit_selling_price'] )
            + ( $row['ordered_quantity'] * $row['unit_shipping_price'] ));
        // FIXME: cesar lo hizo... seguro q bien.
        return $sub * (1.0 + $row['pcnt_tax'] / 100.0 );
    }

    /**
     *
     * Busca si existe un producto en la orden actual
     * @param int OrderId
     * @param int ProductId
     * @param string ProductType
     * @return Zend_Db_Table_Rowset $row
     */
    public function findProductInOrder( $orderId, $productId, $productType ) {
        $rowset = $this->fetchAll(
            $this->select()
            ->where( 'sales_order_id = ?', $orderId )
            ->where( 'line_type = ?', self::LINE_TYPE_PRODUCT )
            ->where( 'product_id = ?', $productId )
            ->where( 'product_type = ?', $productType )
        );
        if( count( $rowset )) {
            return $rowset[0];
        } else {
            return false;
        }
    }

    public function getLinesFromOrder($orderId ) {
        $rowset = $this->fetchAll(
            $this->select()
            ->from( array('sol'=>'sc_sales_order_line' ), array('*'))
            ->where('sol.sales_order_id =?', $orderId )
            ->order( 'sol.line_order')
        );
        if( count( $rowset )) {
            $i=0;
            $salesProperty = new CartWS_Model_SalesLineProperty();
            $result = array();
            foreach( $rowset as $row ) {
                $result[$i] = $row->toArray();
                $result[$i]['properties'] = $salesProperty->getLineProperty( $row->sales_line_id );
                $i++;
            }
            return $result;
        }
        return array();
    }

	public function deleteLinesByType( $orderId, $types )
	{
        $where = array( $this->getAdapter()->quoteInto("sales_order_id = ? ", $orderId ) ,
            "line_type in ( " . $this->getAdapter()->quote( $types ) ." ) " );
        $this->delete( $where );
    }
    
    public function sumLines( $orderId, $types = null ) {
        $sql = $this
        ->getAdapter()
        ->select()
        ->from( $this->_name, array( new Zend_Db_Expr( "sum( unit_final_price )" ) ) )
        ->where( $this->getAdapter()->quoteInto("sales_order_id = ? ", $orderId ) );
        if ( $types !== null ) {
            $sql->where( "line_type in ( " . $this->getAdapter()->quote( $types ) ." ) " );
        }
        return $this->getAdapter()->fetchOne( $sql );
    }
    
    
	/**
	 *
	 * Agrega un item a la orden.
	 * Si existe un producto igual en la orden, le suma las cantidades.
	 * Si la cantidad final es menor a 1 se borra el item de la orden
	 * @param integer OrderId
	 * @param mixed Line
	 * @return Boolean True
	 */
	public function addOrderLine( $orderId, $line ) 
	{
		$properties = new CartWS_Model_SalesLineProperty();
		$lineRow = $this->findProductInOrder( $orderId, $line['product_id'], $line['product_type'] );
		if( $lineRow === false ) {
			if( empty($line['line_type'])) {
				$line['line_type'] = self::LINE_TYPE_PRODUCT;
				$line['line_order'] = $this->getNextProductLineOrder( $orderId );
			}
			$lineRow = $this->createRow();
			$lineRow->setFromArray($line);
			$lineRow->unit_final_price = $this->calculateFinalPrice( $lineRow );
			$lineRow->sales_order_id = $orderId;
			$lineId = $lineRow->save();
			if( isset( $line['properties'] ) ) {
				$properties->addProperties( $lineId, $line['properties'] );
			}
		} else {
			$lineRow->ordered_quantity += $line['ordered_quantity'];
			if( $lineRow->ordered_quantity < 1 ) {
				$properties->deleteFromLine( $lineRow->sales_line_id );
				$lineRow->delete();
			} else {
				$lineRow->unit_final_price = $this->calculateFinalPrice ( $lineRow );
				if( isset( $line['properties'] ) ) {
					$properties->addProperties( $lineRow->sales_line_id, $line['properties'] );
				}
				$lineRow->save();
			}
		}
		return true;
	}
    
	private function getNextProductLineOrder( $orderId )
	{
		$query = $this->select()
			->from( $this->_name, array('max_order'=> 'MAX(line_order)') )
			->where( 'line_type =?',self::LINE_TYPE_PRODUCT )
			->where( 'sales_order_id = ?', $orderId );

		$ret = $this->fetchRow($query);
		error_log(print_r($ret->toArray(),true));
		return (empty($ret) )?self::INIT_LINE_ORDER: ++$ret->max_order;
	}
}